package com.chixing.util;

import com.chixing.pojo.BasePojo;
import com.mongodb.client.result.UpdateResult;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;

@Component
public class MongodbUtils {
    private static MongoTemplate mongoTemplate;

    public static void config(MongoTemplate mongoTemplate) {
        MongodbUtils.mongoTemplate = mongoTemplate;
    }


    public static MongoTemplate getMongoTemplate() {
        return mongoTemplate;
    }


    public static BasePojo add(BasePojo basePojo, String collectionName) {
        BasePojo entity = mongoTemplate.insert(basePojo, collectionName);
        return entity;
    }

    public static <T> T insert(T objectToSave, String collectionName) {
        return mongoTemplate.insert(objectToSave, collectionName);
    }

    public static <T> Collection<T> addList(Collection<? extends T> batchToSave, String collectionName) {
        return mongoTemplate.insert(batchToSave, collectionName);
    }

    public static UpdateResult update(BasePojo basePojo, Update update, String collectionName) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(basePojo.getObjectId()));
        UpdateResult result = mongoTemplate.updateFirst(query, update, collectionName);
        return result;
    }

    public static UpdateResult update(Query query, Update update, String collectionName) {
        UpdateResult result = mongoTemplate.updateFirst(query, update, collectionName);
        return result;
    }

    public static void delete(Long id, String collectionName) {
        mongoTemplate.remove(id, collectionName);
    }

    public static void delete(BasePojo basePojo, String collectionName) {
        mongoTemplate.remove(basePojo, collectionName);
    }

    public static void remove(Query query, String collectionName) {
        mongoTemplate.remove(query, collectionName);
    }

    public static void dropCollection(String collectionName) {
        mongoTemplate.dropCollection(collectionName);
    }

    public static BasePojo findOne(Long id, String collectionName) {
        Query query = new Query(Criteria.where("id").is(id));
        BasePojo basePojo = mongoTemplate.findOne(query, BasePojo.class, collectionName);
        return basePojo;
    }

    public static <T> T findOneData(Class<T> clazz, Query query, String collectionName) {
        return mongoTemplate.findOne(query, clazz, collectionName);
    }

    public static <T extends BasePojo> List<T> findAll(Class<T> clazz, String collectionName) {
        return mongoTemplate.findAll(clazz, collectionName);
    }

    public static <T extends BasePojo> List<T> find(Query query, Class<T> clazz, String collectionName) {
        return mongoTemplate.find(query, clazz, collectionName);
    }

    /**
     * 分页方法
     *
     * @param query
     * @param pageNo
     * @param pageSize
     * @param sort     null不排序
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T extends BasePojo> List<T> page(Query query,
                                                    int pageNo,
                                                    int pageSize,
                                                    Sort sort,
                                                    Class<T> clazz, String collectionName) {
        if (query != null) {
            query.with(PageRequest.of(pageNo, pageSize));
            if (sort != null) {
                query.with(sort);
            }
        }
        return mongoTemplate.find(query, clazz, collectionName);
    }


    public static <T extends BasePojo> long count(Query query, Class<T> clazz, String collectionName) {
        return mongoTemplate.count(query, clazz, collectionName);
    }

    public static <T extends BasePojo> T max(Query query, Class<T> clazz, String collectionName, String fieldName) {

        return mongoTemplate.findOne(query.with(Sort.by(Sort.Order.desc(fieldName))).skip(0).limit(1), clazz, collectionName);
    }

    public static <T extends BasePojo> T min(Query query, Class<T> clazz, String collectionName, String fieldName) {

        return mongoTemplate.findOne(query.with(Sort.by(Sort.Order.asc(fieldName))).skip(0).limit(1), clazz, collectionName);
    }

    public static <O> AggregationResults<O> aggregate(Aggregation aggregation, String collectionName, Class<O> var2) {

        return mongoTemplate.aggregate(aggregation, collectionName, var2);
    }

    public static <T> Collection<T> queryList(Query query,
                                              Class<T> clazz, String collectionName) {
        return mongoTemplate.find(query, clazz, collectionName);
    }

    public static long total(Query query, String collectionName) {
        return mongoTemplate.count(query, collectionName);
    }

    public static <T> T queryOne(Query query, Class<T> entityClass, String collectionName) {
        return mongoTemplate.findOne(query, entityClass, collectionName);
    }

    public static void main(String[] args) {

    }
}

